package com.tianruan.dc.modules.sys.user.api;

import cn.hutool.core.util.StrUtil;
import com.tianruan.dc.modules.BigModelNew.component.XfXhStreamClient;
import com.tianruan.dc.modules.BigModelNew.config.XfXhConfig;
import com.tianruan.dc.modules.BigModelNew.dto.MsgDTO;
import com.tianruan.dc.modules.BigModelNew.listener.XfXhWebSocketListener;
import com.tianruan.dc.common.utils.response.VResponse;
import com.tianruan.dc.modules.sys.user.entity.Result;
import com.tianruan.dc.modules.sys.user.entity.Work;
import com.tianruan.dc.modules.sys.user.entity.WorkInfo;
import com.tianruan.dc.modules.sys.user.service.WorkInfoService;
import com.tianruan.dc.modules.sys.user.service.WorkService;
import com.tianruan.dc.modules.sys.user.utils.PageBean;
import lombok.extern.slf4j.Slf4j;
import okhttp3.WebSocket;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Author: Vivienne
 */
@RestController
@RequestMapping("/api/work")
@Slf4j
public class WorkController {
    @Autowired
    private WorkService workService;
    @Autowired
    private WorkInfoService workInfoService;
    @Resource
    private XfXhStreamClient xfXhStreamClient;
    @Resource
    private XfXhConfig xfXhConfig;


    //教师端新增作文号功能
    @PostMapping("/add")
    //授权
    @PreAuthorize("hasAnyAuthority('sys:super:admin','sys:teacher')")
    public VResponse insertUser(@RequestParam(value = "username") String username,
                             @RequestParam(value = "tile") String tile){
        Work work = workService.insert(username,tile);
        return VResponse.success("新增作文号是："+work.getWorkId());
    }

    //学生新增作文内容

    //根据作业号查询作文题目
    @GetMapping("/{workId}")
    //授权
    @PreAuthorize("hasAnyAuthority('sys:super:admin','sys:teacher','sys:student')")
    public Work findWork(@PathVariable String workId){
        Work work=workService.getByWorkId(workId);
        return work;

    }

    //学生新增（提交）作文内容
     @PostMapping("/insert")
     //授权
     @PreAuthorize("hasAnyAuthority('sys:super:admin','sys:student')")
     public VResponse insertContent(@RequestParam(value = "username") String username,
                                 @RequestParam(value = "content") String content,
                                 @RequestParam(value = "workId") String workId
                                 ) {
         Work work=workService.getByWorkId(workId);
         String userId = work.getWorkId();
         workInfoService.insertContent(username,content,userId);
         return VResponse.success("提交作文成功！");
    }

    //学生修改作文内容
    @PutMapping("/update")
    //授权
    @PreAuthorize("hasAnyAuthority('sys:super:admin','sys:student')")
    public VResponse update(@RequestBody WorkInfo workInfo){
        int row=workInfoService.updateWorkInfo(workInfo);
        if (row > 0) {
            return VResponse.success("修改成功！");
        } else {
            return VResponse.error(1000,"修改失败，未找到匹配的记录或更新内容未改变！");
        }
    }

    //查询作文内容
    @GetMapping("/find")
    //授权
    @PreAuthorize("hasAnyAuthority('sys:super:admin','sys:teacher','sys:student')")
    public VResponse getWorkInfo( @RequestParam(value = "username",required = false) String username,
                                 @RequestParam(value = "workId",required = false) String workId){
        WorkInfo info = workInfoService.getWorkInfo(username,workId);
        if(info==null){
            return VResponse.error(1001,"该用户没有作文信息！");
        }
        return VResponse.success(info);

    }

    //作文号分页查询
    @GetMapping("/workPage")
    //授权
    @PreAuthorize("hasAnyAuthority('sys:super:admin','sys:teacher','sys:student')")
    public VResponse<PageBean<Work>> pageWork(
            @RequestParam(defaultValue = "1")  Integer page,
            @RequestParam(defaultValue = "10")  Integer pageSize,
            @RequestParam(value = "workId",required = false) String workId
    ){
        PageBean<Work> work=workService.PageWork(page,pageSize,workId);
        return VResponse.success(work);
    }
    //作文内容分页查询
    @GetMapping("/workInfoPage")
    //授权
    @PreAuthorize("hasAnyAuthority('sys:super:admin','sys:teacher','sys:student')")
    public VResponse<PageBean<WorkInfo>> pageWorkInfo(
            @RequestParam(defaultValue = "1")  Integer page,
            @RequestParam(defaultValue = "10")  Integer pageSize,
            @RequestParam(value = "workId",required = false) String workId
    ){
        PageBean<WorkInfo> workInfo=workService.PageWorkInfo(page,pageSize,workId);
        return VResponse.success(workInfo);
    }

    /**
     * 发送问题
     *
     * @param workInfo 问题
     * @return 星火大模型的回答
     */
    @PostMapping("/sendQuestion")
    public VResponse sendQuestion(@RequestBody WorkInfo workInfo) {
        //拼接题目
        String allContent = workInfoService.getTitle(workInfo.getId()) + "\n\n" +workInfo.getContent();
        workInfo.setContent(allContent);
        // 存入接口地址
        xfXhConfig.setHostUrl("https://spark-openapi.cn-huabei-1.xf-yun.com/v1/assistants/4t9phxzemz8x_v1");
        // 如果是无效字符串，则不对大模型进行请求nio
        if (StrUtil.isBlank(workInfo.getContent())) {
            return VResponse.error(1000,"无效问题，请重新输入") ;
        }
        // 获取连接令牌
        if (!xfXhStreamClient.operateToken(XfXhStreamClient.GET_TOKEN_STATUS)) {
            return VResponse.error(1001,"当前大模型连接数过多，请稍后再试");
        }

        // 创建消息对象
        MsgDTO msgDTO = MsgDTO.createUserMsg(workInfo.getContent());
        // 创建监听器
        XfXhWebSocketListener listener = new XfXhWebSocketListener();
        // 发送问题给大模型，生成 websocket 连接
        WebSocket webSocket = xfXhStreamClient.sendMsg(UUID.randomUUID().toString().substring(0, 10), Collections.singletonList(msgDTO), listener);
        if (webSocket == null) {
            // 归还令牌
            xfXhStreamClient.operateToken(XfXhStreamClient.BACK_TOKEN_STATUS);
            return VResponse.error(1002,"系统内部错误，请联系管理员");
        }
        try {
            int count = 0;
            // 为了避免死循环，设置循环次数来定义超时时长
            int maxCount = xfXhConfig.getMaxResponseTime() * 5;
            while (count <= maxCount) {
                Thread.sleep(200);
                if (listener.isWsCloseFlag()) {
                    break;
                }
                count++;
            }
            if (count > maxCount) {
                return VResponse.error(1003,"大模型响应超时，请联系管理员");
            }
            //重新存入content <!!!!这里获得返回的数据!!!!>
            String content = listener.getAnswer().toString();
            //提取作文分数
//            System.out.println(content);
            Pattern pattern = Pattern.compile("(\\d{1,3})分");
            Matcher matcher = pattern.matcher(content);
            String score;
            if (matcher.find()) {
                //匹配到的分数 score
                score = matcher.group(1);
            } else {
                return VResponse.error(1004,"请重新认真输入作文");
            }
            msgDTO.setContent(content);
            // 响应大模型的答案
            workInfoService.updateScore(workInfo.getId(),score,content);
            workInfo.setScore(score);
            workInfo.setComments(content);
            return VResponse.success(workInfo.getScore(),workInfo.getComments());

        } catch (InterruptedException e) {
            log.error("错误：" + e.getMessage());
            return VResponse.error(1002,"系统内部错误，请联系管理员");
        } finally {
            // 关闭 websocket 连接
            webSocket.close(1000, "");
            // 归还令牌
            xfXhStreamClient.operateToken(XfXhStreamClient.BACK_TOKEN_STATUS);
        }
    }



}
